package service;

import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;
import java.util.TreeSet;

import titt.TITT;

public class Connector2 {

	private int i = 0;
	
	private final Set<String> services = new HashSet<String>();
	private final Set<String[]> connections = new TreeSet<String[]>(new Comparator<String[]>() {

		@Override
		public int compare(String[] o1, String[] o2) {
			int c;
			for(int i = 0; i < Math.min(o1.length, o2.length); i++) {
				c = o1[i].compareTo(o2[i]);
				if(c != 0)
					return c;
			}
			return o1.length - o2.length;
		}
	});
	private final Set<String[]> activeconnections = new TreeSet<String[]>(new Comparator<String[]>() {

		@Override
		public int compare(String[] o1, String[] o2) {
			int c;
			for(int i = 0; i < Math.min(o1.length, o2.length); i++) {
				c = o1[i].compareTo(o2[i]);
				if(c != 0)
					return c;
			}
			return o1.length - o2.length;
		}
	});
	
	
	private final HashMap<String, Set<String>> triggerToServices = new HashMap<String, Set<String>>();
	private final HashMap<String, Updater2> triggerToUpdater = new HashMap<String, Updater2>();
	
	public String generateID() {
		return ""+i++;
	}
	
	
	public String[] getAllServices() {
		String[] s = new String[services.size()];
		services.toArray(s);
		return s;
	}
	
	public String[][] getAllConnections() {
		String[][] c = new String[connections.size()][];
		connections.toArray(c);
		return c;
	}
	
	public String[][] getAllActiveConnections() {
		String[][] c = new String[activeconnections.size()][];
		activeconnections.toArray(c);
		return c;
	}

	private void updateActives() {
		for(String otherTrigger : triggerToUpdater.keySet())
			triggerToUpdater.get(otherTrigger).updateActives(getAllActiveConnections());
	}
	
	private void update(String trigger) {
		for(String otherTrigger : triggerToUpdater.keySet())
			if(!trigger.equals(otherTrigger)) {
				System.out.println("updating " + otherTrigger);
				triggerToUpdater.get(otherTrigger).update(getAllServices(), getAllConnections());
			}
	}
	
	public void serviceRemoved(String trigger, String service) {
		if(triggerToServices.containsKey(trigger)) {
			triggerToServices.get(trigger).remove(service.toLowerCase());
			services.remove(service.toLowerCase());
			update(trigger);
		}
		
	}
	
	public void serviceAdded(String trigger, String service) {
		if(triggerToServices.containsKey(trigger)) {
			triggerToServices.get(trigger).add(service.toLowerCase());
			services.add(service.toLowerCase());
			update(trigger);
		}
	}
	
	public void connectionActive(String[] connection) {
		activeconnections.add(connection);

		updateActives();
		
	}
	
	public void connectionIdle(String[] connection) {
		activeconnections.remove(connection);

		updateActives();
	}
	
	public void connectionAdded(String trigger, String[] connection) {
		connections.add(connection);

		update(trigger);
	}
	
	public void connectionRemoved(String trigger, String[] connection) {
		connections.remove(connection);
		
		update(trigger);
	}
	
	public void tittRemoved(String[] tokens) {
		String trigger = tokens[1];
		for(String service : triggerToServices.get(trigger)) {
			Set<String[]> copy = new HashSet<String[]>();
			copy.addAll(connections);

			for(String[] connection : copy)
				if(service.equalsIgnoreCase(connection[0]) || service.equalsIgnoreCase(connection[1])) {
					connections.remove(connection);
					activeconnections.remove(connection);
				}
			services.remove(service);
		}
		triggerToServices.remove(trigger);
		triggerToUpdater.remove(trigger);
		
		update(trigger);
	}
	
	public void tittAdded(String[] tokens) {
		String trigger = tokens[1];
		triggerToServices.put(trigger, new HashSet<String>());
		triggerToUpdater.put(trigger, TITT.createProxy(Updater2.class, tokens));

	}
		
}
